import random

import pyautogui
from DrissionPage._pages.chromium_tab import ChromiumTab
from DrissionPage.common import Actions
from DrissionPage.errors import *

import lib.utils.log_loader as log_loader
from lib.utils.config_loader import load_config


def checkbox_click(tab: ChromiumTab):
    """
    点击风控检查按钮。

    对于页面中的风控检查（如验证码），此函数模拟鼠标移动到特定元素（验证码区域）并进行点击。

    :param tab:
    :return: 无返回值。
    """
    logger = log_loader.get_logger()

    try:

        # 先判断是否有风控检查
        ele = tab.ele('#turnstile-wrapper')
        if len(ele.html) < 20:
            return

        # 读取cloudflare.ini配置文件，如果存在则设置Chrome窗口位置和窗口大小
        # 为后面绕过Cloudflare盾时使用。
        cloudflare_config = config_load()
        tab.set.window.location(cloudflare_config['window_location_x'], cloudflare_config['window_location_y'])
        tab.set.window.size(cloudflare_config['window_width'], cloudflare_config['window_height'])

        # 获取页面窗口位置
        window_x, window_y = tab.rect.window_location
        # 创建动作链对象
        ac = Actions(tab)
        tab.set.window.show()

        # 定位到风控检查相关的元素
        # 获取页面中的所有iframe
        iframe = tab.get_frames()
        # 在第一个iframe中定位到具体的点击框元素
        ele = iframe[0].ele('#challenge-stage')

        # 计算目标点击位置，加入随机偏移，以模拟真实用户操作
        iframe_x, iframe_y = iframe[0].rect.location
        mark_x, mark_y = ele.ele('.mark').rect.location
        target_x = window_x + iframe_x + mark_x + cloudflare_config['offset_x'] + random.randint(1, 10)
        target_y = window_y + iframe_y + mark_y + cloudflare_config['offset_y'] + random.randint(1, 10)

        # 移动鼠标到目标位置并点击
        pyautogui.moveTo(target_x, target_y)
        pyautogui.click()

        # 等待一段时间，模拟用户操作的延迟
        ac.wait(random.randint(3, 5))
        # 等待页面加载开始
        # page.wait.load_start()
        logger.debug("反cloudflare操作完成，等待页面加载完成")
        tab.wait.doc_loaded()

    except ElementNotFoundError:
        # 如果找不到指定元素，则打印错误信息
        # logger.error(f"没有找到风控检查")
        pass
    except Exception as e:
        # 打印其他未知错误信息
        logger.error(f"未知错误：{e}")


# 全局变量用于存储配置字典
global_config = None


def config_load(config_file_path='cloudflare.ini'):
    """
    加载配置文件。

    该函数从指定的配置文件中读取相关设置，并将其组织成一个字典返回。
    配置文件中应包含Chrome窗口设置（位置和大小）以及Cloudflare偏移量设置。

    :return: 返回一个包含各种配置的字典，键值对包括Chrome窗口的坐标和大小，以及Cloudflare的偏移量。
    """
    global global_config
    # 如果全局配置已经加载，则直接返回
    if global_config is not None:
        return global_config

    # 加载配置文件
    config_file = load_config(config_file_path)
    # 定义配置项列表
    config_keys = [
        ('chrome', 'window_location_x'),
        ('chrome', 'window_location_y'),
        ('chrome', 'window_width'),
        ('chrome', 'window_height'),
        ('cloudflare', 'offset_x'),
        ('cloudflare', 'offset_y'),
    ]
    # 初始化配置字典
    config = {}
    # 循环读取配置项
    for section, key in config_keys:
        try:
            # 尝试从配置文件读取并转换为整数
            config[key] = int(config_file.get(section, key))
        except ValueError:
            # 如果转换失败，记录错误并使用默认值0
            print(f"配置项 {section}:{key} 转换为整数失败")
            exit()

    # 将加载的配置存储到全局变量中
    global_config = config
    return config
